import * as os from 'os';
import * as path from 'path';
import * as fs from 'fs';
import { exec } from 'child_process';
import { promisify } from 'util';

const execAsync = promisify(exec);

/**
 * 平台类型枚举
 */
enum PlatformType {
    WINDOWS = 'windows',
    MACOS = 'macos',
    LINUX = 'linux',
    WSL = 'wsl'
}

/**
 * 独立测试用的平台检测工具类
 */
class PlatformDetector {
    private static instance: PlatformDetector;
    private platformType: PlatformType;
    private isWSL: boolean = false;
    private isRootless: boolean = false;
    private isAdmin: boolean = false;

    private constructor() {
        // 初始化时检测平台类型
        const platform = os.platform();
        
        if (platform === 'win32') {
            this.platformType = PlatformType.WINDOWS;
        } else if (platform === 'darwin') {
            this.platformType = PlatformType.MACOS;
        } else if (platform === 'linux') {
            this.platformType = PlatformType.LINUX;
            // 检测 WSL
            try {
                const releaseContent = fs.readFileSync('/proc/version', 'utf8').toLowerCase();
                this.isWSL = releaseContent.includes('microsoft') || releaseContent.includes('wsl');
                if (this.isWSL) {
                    this.platformType = PlatformType.WSL;
                }
            } catch (error) {
                // 不是 WSL
            }
        } else {
            // 默认为 Linux
            this.platformType = PlatformType.LINUX;
        }
    }

    public static getInstance(): PlatformDetector {
        if (!PlatformDetector.instance) {
            PlatformDetector.instance = new PlatformDetector();
        }
        return PlatformDetector.instance;
    }

    public getPlatformType(): PlatformType {
        return this.platformType;
    }

    public isWindows(): boolean {
        return this.platformType === PlatformType.WINDOWS;
    }

    public isMacOS(): boolean {
        return this.platformType === PlatformType.MACOS;
    }

    public isLinux(): boolean {
        return this.platformType === PlatformType.LINUX && !this.isWSL;
    }

    public isWSLEnvironment(): boolean {
        return this.isWSL;
    }

    public isRootlessEnvironment(): boolean {
        return this.isRootless;
    }

    public isAdminPrivileged(): boolean {
        return this.isAdmin;
    }

    public async checkUserPrivileges(): Promise<void> {
        try {
            if (this.isWindows()) {
                // Windows 权限检查
                try {
                    await execAsync('net session >nul 2>&1');
                    this.isAdmin = true;
                } catch {
                    this.isAdmin = false;
                }
            } else {
                // macOS/Linux 权限检查
                const { stdout } = await execAsync('id -u');
                this.isAdmin = stdout.trim() === '0';
            }
            
            // 检查容器运行时是否为 rootless 模式
            await this.checkRootlessContainerRuntime();
        } catch (error) {
            console.log('User privileges check error:', error);
            this.isAdmin = false;
        }
    }

    private async checkRootlessContainerRuntime(): Promise<void> {
        try {
            // 检查 Docker 是否运行在 rootless 模式
            try {
                const { stdout: dockerInfo } = await execAsync('docker info 2>/dev/null || echo "Docker not available"');
                this.isRootless = dockerInfo.includes('rootless') || dockerInfo.includes('Rootless');
                
                if (!this.isRootless) {
                    // 如果 Docker 不是 rootless 模式，检查 Podman
                    try {
                        const { stdout: podmanInfo } = await execAsync('podman info 2>/dev/null || echo "Podman not available"');
                        // Podman 默认是 rootless 的，但我们仍然明确检查
                        this.isRootless = podmanInfo.includes('rootless') || !podmanInfo.includes('Podman not available');
                    } catch {
                        // Podman 可能不可用，保持之前的值
                    }
                }
            } catch (error) {
                // Docker 命令失败，忽略
            }
        } catch (error) {
            console.log('Rootless check error:', error);
            this.isRootless = false;
        }
    }

    public isPrivilegedPort(port: number): boolean {
        // Windows 没有特权端口的概念
        if (this.isWindows()) {
            return false;
        }
        
        // 在 Unix 系统上，小于 1024 的端口被认为是特权端口
        return port < 1024;
    }

    public suggestNonPrivilegedPort(desiredPort: number): number {
        if (desiredPort >= 1024) {
            return desiredPort; // 已经是非特权端口
        }
        
        // 为特权端口建议一个替代端口
        const portMap: Record<number, number> = {
            80: 8080,
            443: 8443,
            21: 2121,
            22: 2222,
            25: 2525
        };
        
        return portMap[desiredPort] || 8000 + desiredPort;
    }

    public async convertPathForContainer(originalPath: string): Promise<string> {
        try {
            if (this.isWSL) {
                // 如果是 WSL 环境，需要将路径转换为 Windows 路径
                try {
                    const { stdout } = await execAsync(`wslpath -w "${originalPath}"`);
                    return stdout.trim();
                } catch {
                    return originalPath;
                }
            } else if (this.isWindows()) {
                // Windows 环境下，需要处理路径分隔符
                return originalPath.replace(/\\/g, '/');
            } else {
                // macOS 和 Linux 可以直接使用路径
                return originalPath;
            }
        } catch (error) {
            console.error('Path conversion error:', error);
            return originalPath; // 转换失败时返回原路径
        }
    }

    public getContainerOptions(containerType: 'docker' | 'podman'): Record<string, string> {
        const options: Record<string, string> = {};
        
        if (this.isWSL && containerType === 'docker') {
            // WSL 环境中的 Docker 需要特殊处理
            options.host = '-H npipe:////./pipe/docker_engine';
        }
        
        if (this.isWindows() && containerType === 'podman') {
            // Windows 环境下的 Podman 可能需要特殊处理
            options.connection = '--connection podman-machine-default';
        }
        
        return options;
    }

    /**
     * 检测环境
     */
    public async detectEnvironment(): Promise<{
        type: 'podman' | 'docker' | 'none';
        version?: string;
        path?: string;
    }> {
        // 根据平台选择合适的检测顺序
        if (this.isWindows()) {
            // 在 Windows 上优先检测 Docker
            const dockerEnv = await this.checkDocker();
            if (dockerEnv) {
                return dockerEnv;
            }
            
            const podmanEnv = await this.checkPodman();
            if (podmanEnv) {
                return podmanEnv;
            }
        } else {
            // 在 Linux/macOS 上优先检测 Podman
            const podmanEnv = await this.checkPodman();
            if (podmanEnv) {
                return podmanEnv;
            }
            
            const dockerEnv = await this.checkDocker();
            if (dockerEnv) {
                return dockerEnv;
            }
        }
        
        // 如果都没有，返回 none
        return { type: 'none' };
    }

    private async checkPodman(): Promise<{ type: 'podman', version: string, path?: string } | null> {
        try {
            // 获取平台特定的 Podman 命令选项
            const options = this.getContainerOptions('podman');
            const optionsStr = Object.values(options).join(' ');
            
            // 检测 Podman 版本
            const { stdout } = await execAsync(`podman ${optionsStr} --version`);
            const version = stdout.trim();
            
            // 检测 podman 是否真的可用
            await execAsync(`podman ${optionsStr} info`);
            
            return {
                type: 'podman',
                version,
                path: await this.getCommandPath('podman')
            };
        } catch (error) {
            console.log('Podman not available:', error);
            return null;
        }
    }

    private async checkDocker(): Promise<{ type: 'docker', version: string, path?: string } | null> {
        try {
            // 获取平台特定的 Docker 命令选项
            const options = this.getContainerOptions('docker');
            const optionsStr = Object.values(options).join(' ');
            
            // 检测 Docker 版本
            const { stdout } = await execAsync(`docker ${optionsStr} --version`);
            const version = stdout.trim();
            
            // 检测 docker 是否真的可用
            await execAsync(`docker ${optionsStr} info`);
            
            return {
                type: 'docker',
                version,
                path: await this.getCommandPath('docker')
            };
        } catch (error) {
            console.log('Docker not available:', error);
            return null;
        }
    }

    private async getCommandPath(command: string): Promise<string | undefined> {
        try {
            // 根据平台使用不同的命令
            let whichCmd = 'which';
            if (this.isWindows()) {
                whichCmd = 'where';
            }
            
            const { stdout } = await execAsync(`${whichCmd} ${command}`);
            return stdout.trim().split('\n')[0];
        } catch {
            return undefined;
        }
    }
}

/**
 * 平台支持功能测试
 */
async function testCrossPlatformSupport(): Promise<void> {
    console.log('========== 开始测试跨平台支持功能 ==========\n');

    // 获取平台检测器实例
    const platformDetector = PlatformDetector.getInstance();
    
    // 测试平台检测
    console.log('----- 测试平台检测 -----');
    const platformType = platformDetector.getPlatformType();
    console.log(`检测到的平台类型: ${platformType}`);
    console.log(`操作系统: ${os.platform()} ${os.release()}`);
    console.log(`架构: ${os.arch()}`);
    
    if (platformDetector.isWindows()) {
        console.log('✅ 当前是 Windows 平台');
    } else if (platformDetector.isMacOS()) {
        console.log('✅ 当前是 macOS 平台');
    } else if (platformDetector.isWSLEnvironment()) {
        console.log('✅ 当前是 WSL 环境');
    } else if (platformDetector.isLinux()) {
        console.log('✅ 当前是 Linux 平台');
    }
    
    // 测试权限检测
    console.log('\n----- 测试权限检测 -----');
    await platformDetector.checkUserPrivileges();
    console.log(`管理员权限: ${platformDetector.isAdminPrivileged() ? '是' : '否'}`);
    console.log(`Rootless 模式: ${platformDetector.isRootlessEnvironment() ? '是' : '否'}`);
    
    // 测试环境检测
    console.log('\n----- 测试环境检测 -----');
    const environment = await platformDetector.detectEnvironment();
    console.log(`检测到的环境类型: ${environment.type}`);
    if (environment.version) {
        console.log(`环境版本: ${environment.version}`);
    }
    if (environment.path) {
        console.log(`命令路径: ${environment.path}`);
    }
    
    // 测试端口权限
    console.log('\n----- 测试端口权限 -----');
    const testPorts = [80, 443, 8080, 3000];
    for (const port of testPorts) {
        const isPrivileged = platformDetector.isPrivilegedPort(port);
        const suggestedPort = platformDetector.suggestNonPrivilegedPort(port);
        console.log(`端口 ${port} - 特权端口: ${isPrivileged ? '是' : '否'}, 建议端口: ${suggestedPort}`);
        
        if (isPrivileged) {
            if (platformDetector.isMacOS()) {
                console.log(`  macOS端口建议: 使用非特权端口 ${suggestedPort}`);
            } else if (platformDetector.isLinux() || platformDetector.isWSLEnvironment()) {
                console.log(`  Linux/WSL端口建议: 使用非特权端口或设置特殊权限`);
            }
        }
    }
    
    // 测试路径转换
    console.log('\n----- 测试路径转换 -----');
    const testPaths = [
        __dirname,
        path.join(os.homedir(), 'nginx'),
        '/etc/nginx/conf.d/default.conf',
        'C:\\nginx\\conf\\nginx.conf'
    ];
    
    for (const originalPath of testPaths) {
        try {
            const containerPath = await platformDetector.convertPathForContainer(originalPath);
            console.log(`原始路径: ${originalPath}`);
            console.log(`容器路径: ${containerPath}`);
            console.log('---');
        } catch (error) {
            console.error(`转换路径失败: ${originalPath}`, error);
        }
    }
    
    // 测试容器命令适配
    console.log('\n----- 测试容器命令适配 -----');
    const dockerOptions = platformDetector.getContainerOptions('docker');
    const podmanOptions = platformDetector.getContainerOptions('podman');
    
    // 生成适配后的命令示例
    const dockerOptionsStr = Object.values(dockerOptions).join(' ');
    const podmanOptionsStr = Object.values(podmanOptions).join(' ');
    
    console.log(`Docker 命令示例: docker ${dockerOptionsStr} run -d -p 8080:80 nginx:alpine`);
    console.log(`Podman 命令示例: podman ${podmanOptionsStr} run -d -p 8080:80 nginx:alpine`);
    
    // 测试特定平台功能
    console.log('\n----- 测试特定平台功能 -----');
    
    // Windows 特定功能
    if (platformDetector.isWindows()) {
        console.log('Windows 特定功能:');
        console.log('- 路径分隔符转换');
        console.log('- 使用 where 代替 which');
        console.log('- 无特权端口限制');
    }
    
    // macOS 特定功能
    if (platformDetector.isMacOS()) {
        console.log('macOS 特定功能:');
        console.log('- 特权端口处理');
        console.log('- 使用 pfctl 进行端口转发');
    }
    
    // WSL 特定功能
    if (platformDetector.isWSLEnvironment()) {
        console.log('WSL 特定功能:');
        console.log('- WSL 路径转换');
        console.log('- Docker 引擎连接选项');
    }
    
    console.log('\n========== 跨平台支持功能测试完成 ==========');
}

// 执行测试
testCrossPlatformSupport().catch(error => {
    console.error('跨平台支持测试失败:', error);
}); 